#pragma once

#include <gtest/gtest.h>
#include "qlib/tests/db_test/check.h"
#include "qlib/tests/geo_test/random.h"

using namespace qlib;

// qlib和gdstk的多边形对象
Polygon::s_ptr qlib_polygon = Polygon::create();
gdstk::Polygon gdstk_polygon;

// 重置多边形对象，设置相同的随机二维点集
void resert_polygon() {
  qlib_polygon->points = rand_vec2_array();
  gdstk_polygon.point_array = to_gds(qlib_polygon->points);
}

// Polygon类-BoudingBox函数-测试
TEST(PolygonBoundingBoxTest, BasicAssertion) {
  // 重置对象，生成随机点集
  resert_polygon();

  // 调用qlib-BoudingBox
  Vec2dArray qlib_box = qlib_polygon->bounding_box();

  // 调用gdstk-BoudingBox
  gdstk::Vec2 gdstk_box[2] = {};
  gdstk_polygon.bounding_box(gdstk_box[0], gdstk_box[1]);

  // 比较二者执行结果（此处为返回值）是否相同
  EXPECT_EQ(Check::check_vec2d(qlib_box[0], gdstk_box[0]), true);
  EXPECT_EQ(Check::check_vec2d(qlib_box[1], gdstk_box[1]), true);
}

TEST(PolygonScaleTest, BasicAssertion) {
  resert_polygon();

  double sx = rand_double();
  double sy = rand_double();
  gdstk::Vec2 s_factor = {sx, sy};

  Vec2d qlib_center = Vec2d(rand_double(), rand_double());
  gdstk::Vec2 gdstk_center = {qlib_center.x, qlib_center.y};

  qlib_polygon->scale(sx, sy, qlib_center);
  gdstk_polygon.scale(s_factor, gdstk_center);

  EXPECT_EQ(Check::check_vec2d_array(qlib_polygon->points, gdstk_polygon.point_array), true);
}

TEST(PolygonRotateTest, BasicAssertion) {
  resert_polygon();

  double angle = rand_double();
  Vec2d qlib_center = Vec2d(rand_double(), rand_double());
  gdstk::Vec2 gdstk_center = {qlib_center.x, qlib_center.y};

  qlib_polygon->rotate(angle, qlib_center);
  gdstk_polygon.rotate(angle, gdstk_center);

  EXPECT_EQ(Check::check_vec2d_array(qlib_polygon->points, gdstk_polygon.point_array), true);
}

TEST(PolygonTranslateTest, BasicAssertion) {
  resert_polygon();

  double tx = rand_double();
  double ty = rand_double();

  gdstk::Vec2 trans = {tx, ty};

  qlib_polygon->translate(tx, ty);
  gdstk_polygon.translate(trans);

  EXPECT_EQ(Check::check_vec2d_array(qlib_polygon->points, gdstk_polygon.point_array), true);
}

TEST(PolygonMirrorTest, BasicAssertion) {
  resert_polygon();

  Vec2d p0 = {rand_double(), rand_double()};
  Vec2d p1 = {rand_double(), rand_double()};

  gdstk::Vec2 p0_t = {p0.x, p0.y};
  gdstk::Vec2 p1_t = {p1.x, p1.y};

  qlib_polygon->mirror(p0, p1);
  gdstk_polygon.mirror(p0_t, p1_t);

  EXPECT_EQ(Check::check_vec2d_array(qlib_polygon->points, gdstk_polygon.point_array), true);
}

TEST(PolygonTransformTest, BasicAssertion) {
  resert_polygon();

  double magnification = rand_double();
  bool x_reflection = true;
  double rotation = rand_double();
  Vec2d origin = {rand_double(), rand_double()};
  gdstk::Vec2 origin_t = {origin.x, origin.y};

  qlib_polygon->transform(magnification, x_reflection, rotation, origin);
  gdstk_polygon.transform(magnification, x_reflection, rotation, origin_t);

  EXPECT_EQ(Check::check_vec2d_array(qlib_polygon->points, gdstk_polygon.point_array), true);
}